package main

import "fmt"

// Observer 接口：所有观察者（订阅者）都需实现它
type Observer interface {
	Update(itemName string)
	GetID() string
}

// Subject 接口：主题（被观察对象）提供注册、注销、通知方法
type Subject interface {
	Register(o Observer)
	Deregister(o Observer)
	NotifyAll()
}

// Item 是具体的主题，当库存状态变化时通知观察者
type Item struct {
	name         string
	available    bool
	observerList []Observer
}

func NewItem(name string) *Item {
	return &Item{name: name}
}

func (i *Item) Register(o Observer) {
	i.observerList = append(i.observerList, o)
}

func (i *Item) Deregister(o Observer) {
	list := i.observerList
	for idx, obs := range list {
		if obs.GetID() == o.GetID() {
			// 快速删除：用最后一个覆盖并截断
			list[idx] = list[len(list)-1]
			i.observerList = list[:len(list)-1]
			return
		}
	}
}

func (i *Item) NotifyAll() {
	for _, obs := range i.observerList {
		obs.Update(i.name)
	}
}

func (i *Item) Restock() {
	fmt.Printf("商品 '%s' 已上架！\n", i.name)
	i.available = true
	i.NotifyAll()
}

// Customer 是具体观察者，收到通知时执行 Update
type Customer struct {
	id string
}

func NewCustomer(id string) *Customer {
	return &Customer{id: id}
}

func (c *Customer) Update(itemName string) {
	fmt.Printf("通知 %s：商品 '%s' 已上架，赶快下单！\n", c.id, itemName)
}

func (c *Customer) GetID() string {
	return c.id
}

func main() {
	item := NewItem("MacBook Pro")

	alice := NewCustomer("Alice")
	bob := NewCustomer("Bob")
	item.Register(alice)
	item.Register(bob)

	item.Restock()

	// Bob 取消订阅
	item.Deregister(bob)

	fmt.Println("----- 再次上架通知 -----")
	item.Restock()
}
